package cau.se.project.data;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;

import javax.swing.tree.TreeNode;

import cau.se.project.data.method.GroupControl;
import cau.se.project.data.method.RowControl;

public class CLSXGroup extends DSMRow implements GroupControl {

	private List<TreeNode> m_childList;
	
	public CLSXGroup(String name) {
		super(name);
		m_childList = new ArrayList<TreeNode>();
	}

	@Override
	public void addGroupMember(TreeNode element) throws Exception
	{
		insertGroupMember(element, null);
	}

	@Override
	public void insertGroupMember(TreeNode element, TreeNode position) throws Exception
	{
		if(m_childList.contains(element))
			throw new Exception("Duplicate row");
		
		if(position == null) {
			m_childList.add(element);
		}
		else {
			m_childList.add(m_childList.indexOf(position), element);
		}

		// node의 dependency 붙임
		for(RowControl rc: ((RowControl) element).getDepenencyList()) {
			this.setDependency(rc);
		}
		
		((RowControl) element).setParent(this);
	}

	@Override
	public void removeGroupMember(TreeNode element) throws Exception
	{
		for(int i=0; i<m_childList.size(); i++) {
			TreeNode node = m_childList.get(i);
			if(node == element) {
				m_childList.remove(element);
				
				// dependency 제거
				for(RowControl r: ((RowControl) element).getDepenencyList()) {
					removeDependency(r);
				}
			}
			else if(node.isLeaf() == false) {
				// 트리 재귀호출
				((GroupControl)node).removeGroupMember(element);
			}
		}
	}

	/**
	 * group노드는 dependency 중복삽입이 가능
	 */
	@Override
	public void setDependency(RowControl row)
	{
		if(getParent() != null)
			((RowControl)getParent()).setDependency(row);
		// group노드는 dependency 중복삽입이 가능
		m_dependencyList.add(row);
	}

	@Override
	public TreeNode getChildAt(int childIndex)
	{
		return m_childList.get(childIndex);
	}

	@Override
	public int getChildCount()
	{
		return m_childList.size();
	}

	@Override
	public int getIndex(TreeNode node)
	{
		return m_childList.indexOf(node);
	}

	@Override
	public boolean getAllowsChildren()
	{
		return true;
	}

	@Override
	public boolean isLeaf()
	{
		return false;
	}

	@Override
	public Enumeration<TreeNode> children()
	{
		Vector<TreeNode> v = new Vector<TreeNode>(m_childList);
		return v.elements();
	}

	@Override
	public TreeNode findRowByName(String name) {
		for(TreeNode node : m_childList) {
			String nodeName = ((RowControl) node).getName();
			if(nodeName.equals(name)) {
				return node;
			}
			else if(node.isLeaf() == false) {
				GroupControl gc = (GroupControl) node;
				node = gc.findRowByName(name);
				
				if(node != null)
					return node;
			}
		}
		
		return null;
	}

	@Override
	public boolean isDependencyToChild(RowControl row) {
		for(RowControl rc : row.getDepenencyList()) {
			for(int i=0; i<getChildCount(); i++) {
				if(rc == getChildAt(i)) {
					return true;
				}
				else if(getChildAt(i).isLeaf() == false) {
					boolean ret = ((GroupControl)getChildAt(i)).isDependencyToChild(row);
					if(ret)
						return true;
				}
			}
		}
		
		return false;
	}
}
